#include "stopcond.h"

/*
 * StopCondition constructor
 */
StopCondition::StopCondition(Message* msg) {
	stop_on_seconds = 0;
	stop_on_iterations = 0;
	stop_on_snr = 0;
	current_iteration = 0;
	message = msg;
	
	/* 
	 * get current time; should happen as soon as possible since we want to
	 * measure the time it takes for the whole program to run, not individual
	 * compress loops
	 */
	clock_gettime(CLOCK_REALTIME, &time_start);
}



void StopCondition::addStopOnSeconds(int seconds) {
	if (current_iteration==0) {
		stop_on_seconds = 1;
		stop_seconds = seconds;		
	}
	else
		message->printError("StopCondition usage error: addStopOnSeconds called after the first iteration.\n");
}



void StopCondition::addStopOnSNR(double desired_snr) {
	if (current_iteration==0) {
		stop_on_snr = 1;
		stop_snr = desired_snr;		
	}
	else
		message->printError("StopCondition usage error: addStopOnSNR called after the first iteration.\n");
}



void StopCondition::addStopOnIterations(int iterations) {
	if (current_iteration==0) {
		stop_on_iterations = 1;
		stop_iterations = iterations;		
	}
	else
		message->printError("StopCondition usage error: addStopOnIterations called after the first iteration.\n");
}



/*
 * canBeginNewIteration advises the engine if it can start a new image compress
 * iteration.
 */
int StopCondition::canBeginNewIteration() {
	// check that there is at least one stop condition
	// if there is none, simply stop because there is no condition
	if ((!stop_on_seconds)&&(!stop_on_seconds)&&(!stop_on_seconds)) {
		message->printError("No stop condition established. Please specify at least a condition for stopping compression.\n");
		return 0;
	}
	
	if (stop_on_seconds) {
		time_t elapsed;
		
		clock_gettime(CLOCK_REALTIME, &time_current);
		
		elapsed=time_current.tv_sec-time_start.tv_sec;
		if (((int)elapsed)>= stop_seconds)
			return 0;		
	}
	
	if (stop_on_snr)
		if (current_snr<stop_snr)
			return 0;

	if (stop_on_iterations)
		if (current_iteration==stop_iterations)
			return 0;
	
	// if no condition is met, simply start the iteration
	return 1;
}



/*
 * Start a new iteration
 */
void StopCondition::startIteration() {
	current_iteration++;
}



/*
 * Stop current iteration
 */
void StopCondition::finishedIteration(double snr) {
	current_snr = snr;
}



/*
 * Engine must calculate Sound-to-noise ratio when executing
 * finishedIteration?
 */
int StopCondition::needToCalculateSNR() {
	return stop_on_snr;
}



